from pydantic_settings import BaseSettings
from pydantic import BaseModel
from functools import lru_cache
import secrets
from typing import Any, Union


# 创建Settings对象
class Settings(BaseSettings):
    class HttpResponses(BaseModel):
        code: int
        message: str
        data: Any

    # fastapi
    DEBUG: bool = True
    TITLE: str = "FastAPI Admin"
    SUMMARY: str = """
    FastAPI Admin 是一款基于fastapi的后端项目模板
    """
    VERSION: str = "0.0.1"
    OPENAPI_URL: str = "/openapi.txt"
    RESPONSES: dict[int, dict[str, Union[str, type]]] = {
        200: {"description": "成功响应", "model": HttpResponses},
        201: {"description": "创建成功", "model": HttpResponses},
        204: {"description": "无内容"},  # 204 状态码是无响应的，不可以设置返回的内容格式
        400: {"description": "错误请求", "model": HttpResponses},
        401: {"description": "未授权", "model": HttpResponses},
        403: {"description": "禁止访问", "model": HttpResponses},
        404: {"description": "未找到", "model": HttpResponses},
        409: {"description": "资源冲突", "model": HttpResponses},
        422: {"description": "验证错误", "model": HttpResponses},
        500: {"description": "内部服务器错误", "model": HttpResponses},
    }
    # PostgreSQL
    PGSQL_HOST: str
    PGSQL_PORT: int
    PGSQL_USERNAME: str
    PGSQL_PASSWORD: str
    PGSQL_DATABASES: str
    # Redis
    REDIS_PASSWORD: str
    REDIS_HOST: str
    REDIS_PORT: int
    REDIS_DB: int
    # Token
    SECRET_KEY: str = secrets.token_urlsafe(32)
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 60*24

    # Host
    HOSTS: list[str] = ["*"]
    ORIGINS: list[str] = ["*"]
    METHODS: list[str] = ["*"]
    HEADERS: list[str] = ["*"]
    CREDENTIALS: bool = False

    # System
    DEFAULT_ADMIN_USERNAME: str = "fastapi-admin-user"
    DEFAULT_ADMIN_PASSWORD: str = "fastapi-admin-password"
    DEFAULT_USERNAME: str = "fastapi-password"
    DEFAULT_PASSWORD: str = "fastapi-password"

    class Config:
        env_file = ".env"


# 使用lru_cache只创建一次Settings对象
@lru_cache
def get_settings():
    return Settings()


settings = get_settings()
